package com.example.SimpleGateway.controller;

import com.example.SimpleGateway.CommonUtil.HttpUtil;
import com.example.SimpleGateway.constant.Constant;
import com.example.SimpleGateway.model.REQMessage;
import com.example.SimpleGateway.model.RSMessage;
import org.apache.zookeeper.KeeperException;
import org. apache.zookeeper.WatchedEvent;
import org. apache.zookeeper.Watcher;
import org. apache.zookeeper.ZooKeeper;
import org.springframework.http.HttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * Created by qihao on 2018/2/12.
 */
@RestController
@RequestMapping(value = "/gateway")
public class DiscoveryServiceController {
    private static final String CONNECTION_STRING = "127.0.0.1:2181";
    private static final String REGISTRY_ROOT = "/registry";
    private static final int SESSION_TIMEOUT = 50000;
    private static CountDownLatch latch = new CountDownLatch(1);
    private static List<String> caceh = new ArrayList<String>();
    private static ZooKeeper zk;
    static {
        //连接 ZooKeeper
//        try {
//
//        } catch (InterruptedException e) {
//                e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }
    @RequestMapping(value = "/discovery")
    public RSMessage discoveryService(@RequestBody REQMessage message, HttpServletRequest httpRequest){
        StringBuffer errorMessage = new StringBuffer("");
        try {
            ZooKeeper zk = new ZooKeeper(CONNECTION_STRING, SESSION_TIMEOUT, new Watcher() {
                @Override public void process( WatchedEvent event) {
                    if (event.getState() == Event.KeeperState.SyncConnected) {
                        latch.countDown();
                    }
                }
            });
            latch.await();
            //获取 ZooKeeper 客户 端 对象
            System.out.println(zk);
            String serviceNames = httpRequest.getHeader("Service-Name");
            String serviceType = httpRequest.getHeader("Service-Type");
            if(StringUtils.isEmpty(serviceNames)){
                return new RSMessage(Constant.RESULT_ERROR,"Service-Name request header ERROR");
            }
            if(StringUtils.isEmpty(serviceType)){
                return new RSMessage(Constant.RESULT_ERROR,"Service-Type request header ERROR");
            }
            String servicePath = REGISTRY_ROOT + '/' + serviceNames;
            List<String> nodes = zk.getChildren(servicePath,null);
            int size = nodes.size();
            if (size == 0) {
                return new RSMessage(Constant.RESULT_ERROR,"address node is not exist");
            }
            //生成地址节点路径
            String nodeAddre = servicePath +"/" ;
            if (size == 1) {
                //若 只有 一个 地址， 则 获取 该 地址
                nodeAddre += nodes.get(0);
            } else {
                //若 存在 多个 地址， 则 随机 获取 一个 地址
                nodeAddre += nodes.get((int)(Math.random() * size ));
            }
            byte[] serviceURL = zk.getData(nodeAddre,null,null);
            String url = null;
            try{
                url = new String(("http://"+new String(serviceURL) + "/"+serviceNames));
//                uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
            }catch(Exception e){
                e.printStackTrace();
            }
            if(serviceType.equals(Constant.POST_BODY)){
                return  HttpUtil.doPostByBody(url,message.getBody());
            }else if(serviceType.equals(Constant.POST_PARAM)) {
                return HttpUtil.doPostByParams(url, message.getParam());
            }else if(serviceType.equals(Constant.GET_PARAM)){
                return  HttpUtil.doGet(url,message.getParam(),"");
            }else if(serviceType.equals(Constant.GET_PATH)){
                return  HttpUtil.doGet(url,"",message.getPath());
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
            errorMessage.append(e.getMessage() + ";  ");
        } catch (IOException e) {
            e.printStackTrace();
            errorMessage.append(e.getMessage() + ";  ");
        } catch (KeeperException e) {
            e.printStackTrace();
            errorMessage.append(e.getMessage() + ";  ");
        } catch (Exception e) {
            e.printStackTrace();
            errorMessage.append(e.getMessage() + ";  ");
        }
        return new RSMessage(Constant.RESULT_ERROR,"SYSTEM ERROR: " + errorMessage);
    }

}
